﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml;
using GEPSDevelopEnvironment.Common;
using GEPSDevelopEnvironment.Config;
using ListViewItem = System.Windows.Controls.ListViewItem;
using MessageBox = System.Windows.MessageBox;
using Control = System.Windows.Controls.Control;
using CheckBox = System.Windows.Controls.CheckBox;
using Panel = System.Windows.Controls.Panel;

namespace GEPSDevelopEnvironment.Forms
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnOpen_Click(object sender, RoutedEventArgs e)
        {
            ConfigFile.Instance.OpenConfigFile();
            InitUI();
        }

        private void btnImport_Click(object sender, RoutedEventArgs e)
        {
            ConfigFile.Instance.ImportConfigFile();
            InitUI();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (!ConfigFile.Instance.SaveConfigFile())
            {
                MessageBox.Show("当前没有可保存的内容！");
            }
        }

        private void btnNew_Click(object sender, RoutedEventArgs e)
        {
            ConfigFile.Instance.CreateNewConfig();
            InitUI();
        }

        private void lstSelectPath_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            string strContent = oSender.Content as string;
            oSender.Content = strContent.Substring(0, strContent.IndexOf('：') + 1)
                       + "   " + SetPathNodeText((string)oSender.Tag, GetConfigText(oSender));
        }

        private void lstMapppingGRSJunction_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            XmlNode oNode = GetConfigNode(oSender);
            Debug.Assert(oNode != null);
            oNode.InnerText = FileCommonUtils.SelectFile("junction.exe|junction.exe");
            lviMapppingGRSJunction.Content = "junction.exe:     " + oNode.InnerText;
        }

        private void lstRebuildGSPExplorerAdd_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            string strPath = FileCommonUtils.SelectPath();
            ListViewItem oItem = new ListViewItem();
            oItem.Content = strPath;
            lstRebuildGSPExplorer.Items.Insert(lstRebuildGSPExplorer.Items.Count - 1, oItem);
            XmlNode oNode = GetConfigNode(oSender);
            Debug.Assert(oNode != null);
            oNode.InnerText = oNode.InnerText + strPath + ";";
        }

        private void lviCheckOutGEPS5Src_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            XmlNode oNode = GetConfigNode(oSender);
            Debug.Assert(oNode != null);
            string strPath = oNode.InnerText;
            oNode.InnerText = TortoiseSVNClientAdapter.Browse(strPath);
            lviCheckOutGEPS5Src.Content = "源路径:     " + oNode.InnerText;
        }

        private void lviCheckOutGEPS5Dst_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            string strPath = SetPathNodeText((string)oSender.Tag, GetConfigText(oSender));
            lviCheckOutGEPS5Dst.Content = "目标路径：  " + strPath;
            SyncCodePaths(strPath);
            string strGEPS = strPath + "\\Platform";
            
            cbiGEPS5.Content = strGEPS;
        }

        private string SetPathNodeText(string ANodePath, string AInitDir = "")
        {
            XmlNode oNode = ConfigFile.Instance.GetConfigNode(ANodePath);
            Debug.Assert(oNode != null);
            oNode.InnerText = FileCommonUtils.SelectPath(AInitDir);
            return oNode.InnerText;
        }

        private void lviCheckOutGEPS6Src_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            XmlNode oNode = GetConfigNode(oSender);
            Debug.Assert(oNode != null);
            string strPath = oNode.InnerText;
            oNode.InnerText = TortoiseSVNClientAdapter.Browse(strPath);
            lviCheckOutGEPS6Src.Content = "源路径:     " + oNode.InnerText;
        }

        private void lviCheckOutGEPS6Dst_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            ListViewItem oSender = (ListViewItem)sender;
            string strPath = SetPathNodeText((string)oSender.Tag,
                GetConfigText(oSender));
            lviCheckOutGEPS6Dst.Content = "目标路径：  " + strPath;
            SyncCodePaths(strPath);
            string strGEPS = strPath + "\\Platform\\GEPS5";
            cbiGEPS6.Content = strGEPS;
        }

        private void SyncCodePaths(string ACodeRootPath)
        {
            string strCopyGSPToRelease = ACodeRootPath + "\\Platform\\Bin\\CopyGSPToRelease.bat";
            XmlNode oNode = GetConfigNode(lviCopyGSPToRelease);
            Debug.Assert(oNode != null);
            oNode.InnerText = strCopyGSPToRelease;
            lviCopyGSPToRelease.Content = "文件路径：    " + strCopyGSPToRelease;

            string strCopyNativeResources = ACodeRootPath + "\\Platform\\Bin\\Client\\CopyNativeResources.bat";
            oNode = GetConfigNode(lviCopyNativeResources);
            Debug.Assert(oNode != null);
            oNode.InnerText = strCopyNativeResources;
            lviCopyNativeResources.Content = "文件路径：    " + strCopyNativeResources;

            string strJunction = ACodeRootPath + "\\Platform\\Build\\junction.exe";
            oNode = GetConfigNode(lviMapppingGRSJunction);
            Debug.Assert(oNode != null);
            oNode.InnerText = strJunction;
            lviMapppingGRSJunction.Content = "junction.exe：    " + strJunction;
        }

        private void RecurseControls(ICollection uiControls, Type type, Action<Control, object> action, object param)
        {
            foreach (var element in uiControls)
            {
                if (element.GetType() == type)
                {
                    action(element as Control, param);
                }
                if (element is Panel)
                {
                    this.RecurseControls((element as Panel).Children, type, action, param);
                }
                else if (element is ItemsControl)
                {
                    this.RecurseControls((element as ItemsControl).Items, type, action, param);
                }
                else if (element is ContentControl)
                {
                    if ((element as ContentControl).Content is Panel)
                    {
                        Panel sa = (element as ContentControl).Content as Panel;
                        this.RecurseControls(sa.Children, type, action, param);
                    }
                    else if ((element as ContentControl).Content is ContentControl)
                    {
                        ContentControl control = (element as ContentControl).Content as ContentControl;
                        List<ContentControl> controls = new List<ContentControl>();
                        if (control != null)
                        {
                            controls.Add(control);
                            this.RecurseControls(controls as ICollection, type, action, param);
                        }
                    }
                    else if ((element as ContentControl).Content is ItemsControl)
                    {
                        ItemsControl sa = (element as ContentControl).Content as ItemsControl;
                        this.RecurseControls(sa.Items, type, action, param);
                    }
                    if (element is HeaderedContentControl)
                    {
                        if ((element as HeaderedContentControl).Header is Panel)
                        {
                            Panel sa = (element as HeaderedContentControl).Header as Panel;
                            this.RecurseControls(sa.Children, type, action, param);
                        }
                        else if ((element as HeaderedContentControl).Header is ContentControl)
                        {
                            ContentControl control = (element as HeaderedContentControl).Header as ContentControl;
                            List<ContentControl> controls = new List<ContentControl>();
                            if (control != null)
                            {
                                controls.Add(control);
                                this.RecurseControls(controls as ICollection, type, action, param);
                            }
                        }
                        else if ((element as HeaderedContentControl).Header is ItemsControl)
                        {
                            ItemsControl sa = (element as HeaderedContentControl).Header as ItemsControl;
                            this.RecurseControls(sa.Items, type, action, param);
                        }
                    }
                }
            }
        }

        private void SetListViewItemText(Control control, object param)
        {
            ListViewItem item = control as ListViewItem;
            if (item != null)
            {
                string strContent = item.Content as string;
                if (strContent != null)
                {
                    item.Content = strContent.Substring(0, strContent.IndexOf('：') + 1) + "   " + GetConfigText(control);
                }
            }
        }

        private void SetCheckBoxState(Control control, object param)
        {
            CheckBox item = control as CheckBox;
            if (item != null)
            {
                string strContent = GetConfigAttribute(item, "checked");
                if (!string.IsNullOrEmpty(strContent))
                {
                    item.IsChecked = strContent == "true";
                }
                else
                {
                    item.IsChecked = false;
                }
            }
        }

        private void InitUI()
        {
            RecurseControls(this.dkWindow.Children, lviCheckOutGEPS5Dst.GetType(), SetListViewItemText, null);
            RecurseControls(this.dkWindow.Children, chkCheckOutGEPS5.GetType(), SetCheckBoxState, null);
        }

        private void SetControlBackColor(Control AControl, Brush ABrush)
        {
            AControl.Background = ABrush;
            App.DoEvents();
            Thread.Sleep(100);
        }

        private void btnRun_Click(object sender, RoutedEventArgs e)
        {
            string strErrMessage = "";
            int nExitCode;

            RecurseControls(this.dkWindow.Children, epCheckOutGEPS5.GetType(), SetExpanderState, 1);

            //导出GEPS5的代码
            if (chkCheckOutGEPS5.IsChecked == true)
            {
                SetControlBackColor(epCheckOutGEPS5, Brushes.Yellow);
                SVNClientAdapter.CheckOut(GetConfigText(lviCheckOutGEPS5Src),
                                          GetConfigText(lviCheckOutGEPS5Src), out strErrMessage);
                SetControlBackColor(epCheckOutGEPS5, Brushes.Green);
            }

            //导出GEPS6的代码
            if (chkCheckOutGEPS6.IsChecked == true)
            {
                SetControlBackColor(epCheckOutGEPS6, Brushes.Yellow);
                SVNClientAdapter.CheckOut(GetConfigText(lviCheckOutGEPS6Src),
                                          GetConfigText(lviCheckOutGEPS6Dst), out strErrMessage);
                SetControlBackColor(epCheckOutGEPS6, Brushes.Green);
            }

            //拷贝公共资源
            if (chkCopyGRS.IsChecked == true)
            {
                SetControlBackColor(epCopyGRS, Brushes.Yellow);
                FileCommonUtils.CopyFolder(GetConfigText(lviCopyGRSSrc),
                                           GetConfigText(lviCopyGRSDst));
                SetControlBackColor(epCopyGRS, Brushes.Green);
            }

            //映射公共资源
            if (chkMapppingGRS.IsChecked == true)
            {
                SetControlBackColor(epMapppingGRS, Brushes.Yellow);
                FileCommonUtils.DeleteDirectory(GetConfigText(lviMapppingGRSDst));
                ProcessCommonUtils.GetCommandLineOutput(
                    GetConfigText(lviMapppingGRSDst) + " " + GetConfigText(lviMapppingGRSSrc),
                    out nExitCode, GetConfigText(lviMapppingGRSJunction));
                SetControlBackColor(epMapppingGRS, Brushes.Green);
            }

            //修改GQLParser.pas并重新编译GSPExplorer和GEPSSubModelBuilderPlugin
            if (chkRebuildGSPExplorer.IsChecked == true)
            {
                SetControlBackColor(epRebuildGSPExplorer, Brushes.Yellow);
                SetControlBackColor(epRebuildGSPExplorer, Brushes.Green);
            }

            //配置GEPS环境变量
            if (chkGEPSEnv.IsChecked == true)
            {
                SetControlBackColor(epGEPSEnv, Brushes.Yellow);
                Environment.SetEnvironmentVariable("GEPS", GetConfigText(lviGEPSEnv), EnvironmentVariableTarget.Machine);
                Environment.SetEnvironmentVariable("GEPS", GetConfigText(lviGEPSEnv), EnvironmentVariableTarget.User);
                SetControlBackColor(epGEPSEnv, Brushes.Green);
            }

            //执行CopyGSPToRelease.bat
            if (chkCopyGSPToRelease.IsChecked == true)
            {
                SetControlBackColor(epCopyGSPToRelease, Brushes.Yellow);
                ProcessCommonUtils.GetCommandLineOutput(GetConfigText(epCopyGSPToRelease), out nExitCode);
                SetControlBackColor(epCopyGSPToRelease, Brushes.Green);
            }

            //执行CopyNativeResources.bat
            if (chkCopyNativeResources.IsChecked == true)
            {
                SetControlBackColor(epCopyNativeResources, Brushes.Yellow);
                ProcessCommonUtils.GetCommandLineOutput(GetConfigText(epCopyNativeResources), out nExitCode);
                SetControlBackColor(epCopyNativeResources, Brushes.Green);
            }

            //重新编译GSPExplorer

            if (chkRebuildGSPExplorer.IsChecked == true)
            {
                SetControlBackColor(epRebuildGSPExplorer, Brushes.Yellow);
                string strGRSPath = GetConfigText(lviMapppingGRSDst);
                string strGSPExplorer = strGRSPath + "\\GrandSoft\\GrandSmartPlatform";
                if (File.Exists(strGSPExplorer + "\\Common\\GQLParser.pas"))
                {
                    StreamReader oReader = null;
                    StreamWriter oWriter = null;
                    try
                    {
                        Encoding oEncoding = Encoding.GetEncoding("gb2312");
                        oReader = new StreamReader(strGSPExplorer + "\\Common\\GQLParser.pas", oEncoding);
                        string strTmpFile = Path.GetTempFileName();
                        oWriter = new StreamWriter(strTmpFile, true, oEncoding);
                        string strContent =
                            "function GetFullPathFile(const ABaseDir, AFileName: string; ASearchPaths: TStrings): string;";
                        string strLine = oReader.ReadLine();
                        while (strLine != null)
                        {
                            oWriter.WriteLine(strLine);
                            string strNext = oReader.ReadLine();
                            if (strLine.Contains(strContent))
                            {
                                if (strNext.Contains("var"))
                                {
                                    oWriter.WriteLine("const");
                                    oWriter.WriteLine(string.Format("CPlatform='{0}'",
                                                                    GetConfigText(lviGSPExplorerPlatform)));
                                    oWriter.WriteLine(string.Format("CCustomize='{0}'",
                                                                    GetConfigText(lviGSPExplorerCustomize)));
                                    do
                                    {
                                        oWriter.WriteLine(strNext);
                                        strNext = oReader.ReadLine();
                                    } while (strNext.Trim() != "begin");
                                    oWriter.WriteLine(strNext);
                                    oWriter.WriteLine("ASearchPaths.add(CPlatform);");
                                    oWriter.WriteLine("ASearchPaths.add(CCustomize);");
                                    strNext = oReader.ReadLine();
                                }
                                else if (strNext.Contains("const"))
                                {
                                    oWriter.WriteLine(strNext);
                                    oReader.ReadLine();
                                    oWriter.WriteLine(string.Format("CPlatform='{0}';",
                                                                    GetConfigText(lviGSPExplorerPlatform)));
                                    oReader.ReadLine();
                                    oWriter.WriteLine(string.Format("CCustomize='{0}';",
                                                                    GetConfigText(lviGSPExplorerCustomize)));
                                    strNext = oReader.ReadLine();
                                }
                            }
                            strLine = strNext;
                        }
                        oReader.Close();
                        oWriter.Flush();
                        File.Copy(strTmpFile, strGSPExplorer + "\\Common\\GQLParser.pas", true);
                    }
                    catch  
                    {  
                    }  
                    Directory.CreateDirectory(strGSPExplorer + "\\DCU");
                    XmlDocument xmlWant = new XmlDocument();
                    xmlWant.LoadXml(Properties.Resources.Want_xml);
                    xmlWant.SelectSingleNode("project[1]").Attributes["basedir"].Value =
                        strGSPExplorer.Replace("\\", "/");
                    xmlWant.SelectSingleNode("project/property[2]").Attributes["value"].Value = 
                        GetConfigText(lviGEPSEnv).Replace("\\", "/");
                    xmlWant.Save(strGSPExplorer + "\\want.xml");
                    File.WriteAllBytes(strGSPExplorer + "\\want.exe", Properties.Resources.Want_exe);
                    ProcessCommonUtils.GetCommandLineOutput("-buildfile " + strGSPExplorer + "\\want.xml", 
                        out nExitCode, strGSPExplorer + "\\want.exe", strGSPExplorer);
                }
                SetControlBackColor(epRebuildGSPExplorer, Brushes.Green);
            }

            //映射客户端配置文件路径
            //修改Config文件
            //新建数据库
            //还原数据库
            //更新界面
            RecurseControls(this.dkWindow.Children, epCheckOutGEPS5.GetType(), SetExpanderBackColor, null);
        }

        private void SetExpanderBackColor(Control control, object param)
        {
            Expander item = control as Expander;
            if (item != null)
            {
                string strContent = item.Tag as string;
                if (!string.IsNullOrEmpty(strContent) && (strContent != "0"))
                {
                    item.Background = Brushes.Wheat;
                }
            }
        }

        private void SetExpanderState(Control control, object param)
        {
            Expander item = control as Expander;
            if (item != null)
            {
                switch ((int)param)
                {
                    case 1:
                        if ((string)item.Tag == "0")
                        {
                            item.IsExpanded = true;
                        }
                        else
                        {
                            item.IsExpanded = false;
                        }
                        break;
                    case 2:
                        item.IsExpanded = true;
                        break;
                    default:
                        item.IsExpanded = false;
                        break;
                }
            }
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox oSender = (CheckBox)sender;
            XmlNode oNode = GetConfigNode(oSender);
            Debug.Assert(oNode != null);
            oNode.Attributes["checked"].Value = "true";
        }

        private void CheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            CheckBox oSender = (CheckBox)sender;
            XmlNode oNode = GetConfigNode(oSender);
            Debug.Assert(oNode != null);
            oNode.Attributes["checked"].Value = "false";
        }

        private string GetConfigText(Control AItem)
        {
            return ConfigFile.Instance.GetConfigText((string)AItem.Tag);
        }

        private XmlNode GetConfigNode(Control AItem)
        {
            return ConfigFile.Instance.GetConfigNode((string)AItem.Tag);
        }

        private string GetConfigAttribute(Control AItem, string Attribute)
        {
            return ConfigFile.Instance.GetConfigAttribute((string)AItem.Tag, Attribute);
        }

        private void btnCollapse_Click(object sender, RoutedEventArgs e)
        {
            RecurseControls(this.dkWindow.Children, epCheckOutGEPS5.GetType(), SetExpanderState, 0);
        }

        private void btnExpand_Click(object sender, RoutedEventArgs e)
        {
            RecurseControls(this.dkWindow.Children, epCheckOutGEPS5.GetType(), SetExpanderState, 2);
        }

        private void MouseWheel_Event(object sender, MouseWheelEventArgs e)
        {
            svWindow.ScrollToVerticalOffset(svWindow.VerticalOffset - e.Delta / 120 * 25);
        }

        private void cbbGEPSEnv_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            XmlNode oNode = GetConfigNode(lviGEPSEnv);
            Debug.Assert(oNode != null);
            oNode.InnerText = cbbGEPSEnv.Text;
        }
    }
}
